﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using KongMing.Project.Common;
using Microsoft.Extensions.Caching.Memory;
using KongMing.Project.Common.Sdk;

namespace KongMing.Project.WebApi.Controllers
{
    public class MyCacheController : BaseApiController
    {
        private readonly IMemoryCache MCache;
        private readonly ILogger<MyCacheController> Logger;
        public MyCacheController(IServiceProvider serviceProvider) : base(serviceProvider)
        {
            MCache = GetService<IMemoryCache>();
            Logger = GetService<ILogger<MyCacheController>>();
        }

        /// <summary>
        /// 使用客户端缓存，浏览器缓存，30s
        /// </summary>
        [HttpGet]
        [ResponseCache(Duration = 30)]
        public async Task<string> Now_ResponseCache()
        {
            //获取数据...
            await Task.Delay(100);
            var now = Configs.NowTime;
            return now;
        }



        /// <summary>
        /// 使用服务端本地缓存
        /// </summary>
        [HttpGet]
        public async Task<string> Now_IMemoryCache()
        {
            string key = "nowtime";
            string nowtime = string.Empty;
            //方式一：TryGetValue ，缺点：没有异步
            //if(!MCache.TryGetValue(key,out nowtime))
            //{
            //    nowtime = Configs.NowTime;
            //    MCache.Set(key, nowtime, TimeSpan.FromSeconds(30));
            //}
            //方式二 异步 可以规避缓存穿透问题：值为null时候，也会缓存进去
            nowtime = await MCache.GetOrCreateAsync(key, async (e) =>
            {
                ////过期删除策略：绝对过期时间 ：到了指定时间就删除
                //e.AbsoluteExpiration = Configs.Now.AddSeconds(20);//绝对过期时间
                //e.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);//相对与当前时间
                //过期删除策略：滑动过期时间 ：每次访问缓存的时候就重新计算过期时间
                e.SlidingExpiration = TimeSpan.FromSeconds(10);//10s内访问，过期时间就重新设置10s，过了10s删除
                //从数据库读取...
                Logger.LogInformation("从数据库读取...");
                await Task.Delay(100);
                return Configs.NowTime;
            });
            return nowtime;
        }

        /// <summary>
        /// 使用Redis缓存
        /// </summary>
        [HttpGet]
        public async Task<string> Now_RedisCache()
        {
            using var redisClient = new RedisClient(new Entity.Common.RedisConfig() { ConnectionString = "127.0.0.1:6379", InstanceName = "km", DefaultDB = 0 });
            string key = "nowtime";
            var db = redisClient.GetDatabase();
            string nowtime = await db.StringGetAsync(key);
            if (string.IsNullOrEmpty(nowtime))
            {
                nowtime = Configs.NowTime;
                await db.StringSetAsync(key, nowtime,TimeSpan.FromSeconds(10));
            }
            return nowtime;
        }

    }
}
